<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>WebRTC 视频通话</title>
  <style>
    #local-video,
    #remote-video {
      width: 50%;
    }

    #videos-container {
      display: flex;
      justify-content: space-around;
      margin-top: 20px;
    }

    #controls-container {
      display: flex;
      justify-content: space-around;
      margin-top: 20px;
    }

    button {
      font-size: 16px;
    }
  </style>
</head>

<body>
<div id="videos-container">
  <video id="local-video" autoplay controls playsinline></video>
  <video id="remote-video" autoplay controls playsinline></video>
</div>

<div id="controls-container">
  <button id="toggle-audio">麦克风</button>
  <button id="toggle-video">摄像头</button>
  <button id="conn1" onclick="connect(1)">1号连接</button>
  <button id="conn2" onclick="connect(2)">2号连接</button>


  <button id="phone" onclick="phone(2)">1号向2号通话</button>
  <button id="phone2" onclick="phone(1)">2号向1号通话</button>
</div>

<script>
  function connect(id) {
    init(id)
  }
  function phone(to) {
    createPeerConnection(to);
  }

  let localStream, remoteStream, ws;
  const localVideo = document.getElementById('local-video');
  const remoteVideo = document.getElementById('remote-video');
  let peerConnection;

  // 获取本地媒体流（摄像头和麦克风）
  navigator.mediaDevices.getUserMedia({ video: true, audio: true })
          .then((stream) => {
            localStream = stream;
            localVideo.srcObject = stream;
          })
          .catch((error) => {
            console.error('Error accessing media devices:', error);
          });

  function init(id) {
    // 设置信令服务器地址，这里使用 WebSocket
    const sever_url = 'ws://10.195.74.159/websocket2/'

    const signalingServerUrl = sever_url + id;

    ws = new WebSocket(signalingServerUrl);

    ws.addEventListener('open', () => {
      console.log('WebSocket connection opened.');
    });

    // 信令服务器消息处理
    ws.addEventListener('message', (event) => {
      console.log(event)
      const data = JSON.parse(event.data);

      if (data.type === 'offer') {
        let from = data.from
        handleOffer(from,data.offer);
      } else if (data.type === 'answer') {
        handleAnswer(data.answer);
      } else if (data.type === 'ice-candidate') {
        handleICECandidate(data.candidate);
      }
    });
  }


  // 创建对等连接
  function createPeerConnection(to) {
    const configuration = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] };
    peerConnection = new RTCPeerConnection(configuration);

    // 添加本地流到 PeerConnection
    localStream.getTracks().forEach(track => peerConnection.addTrack(track, localStream));

    // 监听远程流的到达
    peerConnection.ontrack = (event) => {
      remoteStream = event.streams[0];
      remoteVideo.srcObject = remoteStream;
    };

    // 监听 ICE Candidate 事件
    peerConnection.onicecandidate = (event) => {
      if (event.candidate) {
        sendICECandidate(event.candidate);
      }
    };

    if (to != -1) {
      // 发送 Offer
      peerConnection.createOffer()
              .then((offer) => {
                return peerConnection.setLocalDescription(offer);
              })
              .then(() => {
                sendOffer(to, peerConnection.localDescription);
              })
              .catch((error) => {
                console.error('Error creating offer:', error);
              });
    }

  }

  // 发送 Offer 到信令服务器
  function sendOffer(to, offer) {
    console.log('send to', to);
    ws.send(JSON.stringify({ 'to': to, type: 'offer', offer }));
  }

  // 处理接收到的 Offer
  function handleOffer(from,offer) {
    createPeerConnection(-1);  // -1表示只接受 不需要发送offer了

    // 设置远程描述
    peerConnection.setRemoteDescription(new RTCSessionDescription(offer));

    // 创建 Answer
    peerConnection.createAnswer()
            .then((answer) => {
              return peerConnection.setLocalDescription(answer);
            })
            .then(() => {
              sendAnswer(from,peerConnection.localDescription);
            })
            .catch((error) => {
              console.error('Error creating answer:', error);
            });
  }

  // 发送 Answer 到信令服务器
  function sendAnswer(from,answer) {
    ws.send(JSON.stringify({'from':from ,type: 'answer', answer }));
  }

  // 处理接收到的 Answer
  function handleAnswer(answer) {
    // 设置远程描述
    peerConnection.setRemoteDescription(new RTCSessionDescription(answer));
  }

  // 发送 ICE Candidate 到信令服务器
  function sendICECandidate(candidate) {
    ws.send(JSON.stringify({ type: 'ice-candidate', candidate }));
  }

  // 处理接收到的 ICE Candidate
  function handleICECandidate(candidate) {
    // 添加远程 ICE Candidate
    peerConnection.addIceCandidate(new RTCIceCandidate(candidate))
            .catch((error) => {
              console.error('Error adding ICE candidate:', error);
            });
  }

  // 切换麦克风状态
  const toggleAudioButton = document.getElementById('toggle-audio');
  toggleAudioButton.addEventListener('click', () => {
    localStream.getAudioTracks().forEach(track => {
      track.enabled = !track.enabled;
    });
  });

  // 切换摄像头状态
  const toggleVideoButton = document.getElementById('toggle-video');
  toggleVideoButton.addEventListener('click', () => {
    localStream.getVideoTracks().forEach(track => {
      track.enabled = !track.enabled;
    });
  });

  // 获取音量调节滑块
  const volumeSlider = document.getElementById('volume-slider');

  // 当音量滑块值发生变化时
  volumeSlider.addEventListener('input', () => {
    setLocalStreamVolume(volumeSlider.value);
  });

  // 设置本地流的音量
  function setLocalStreamVolume(volume) {
    localStream.getAudioTracks().forEach(track => {
      const audioElement = document.getElementById('local-video');
      const audioHandler = new RTCVolumeHandler(track);
      audioHandler.volume = volume;
      audioElement.volume = volume;
    });
  }
</script>
</body>

</html>